home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / hypercar / xcmd / dartxcmd.sit / Dartmouth XCMD's 3.1 / card_16339.txt < prev    next >
Encoding:
Text File  |  1989-06-02  |  48.9 KB  |  1,575 lines

  1. -- card: 16339 from stack: in.1
  2. -- bmap block id: 16385
  3. -- flags: 0000
  4. -- background id: 7836
  5. -- name: MenuHandler
  6. ----- HyperTalk script -----
  7.  
  8. on closecard
  9.   RemoveMenu
  10.   set the name of btn 1 to "Install Menu"
  11. end closecard
  12.  
  13. on InstallMenu
  14.   global ExampleMenu
  15.   put "(Disabled,Check,Test/A" into ExampleMenu
  16.   MenuHandler "Add","Example",ExampleMenu
  17.   MenuHandler "Disable","Go","Back"
  18.   answer "Disabled HyperCard's 'go Back' menu item."
  19. end InstallMenu
  20.  
  21. on RemoveMenu
  22.   MenuHandler "Delete",Example
  23.   MenuHandler "Enable","Go","Back"
  24. end RemoveMenu
  25.  
  26. on domenu anItem
  27.   global ExampleMenu, Disabled
  28.   --anItem is the name of the menu item choosen
  29.   -- HelpMenu is a list of items in my own help menu
  30.   -- Disabled is the list of items that I have disabled
  31.   if Disabled contains anItem then
  32.     answer "HyperCard menu item "&anItem&" is disabled" with "OK"
  33.     exit domenu
  34.   else if ExampleMenu contains anItem then
  35.     DoExample anItem -- see which item it is and do something
  36.   else   -- is an enable HyperCard item
  37.     pass domenu -- pass it on down the line
  38.     exit domenu
  39.   end if
  40. end domenu
  41.  
  42. on DoExample anItem
  43.   global checked
  44.   if anItem is "Check" then
  45.     if checked is not true then
  46.       MenuHandler "Mark","Example","Check",check
  47.       put true into checked
  48.     else
  49.       MenuHandler "Mark","Example","Check",none
  50.       put false into checked
  51.     end if
  52.   else if anItem is "Test" then
  53.     answer "You have chosen the Test menu item."
  54.   end if
  55. end DoExample
  56.  
  57.  
  58.  
  59. -- part 3 (button)
  60. -- low flags: 00
  61. -- high flags: A003
  62. -- rect: left=76 top=298 right=320 bottom=176
  63. -- title width / last selected line: 0
  64. -- icon id / first selected line: 0 / 0
  65. -- text alignment: 1
  66. -- font id: 0
  67. -- text size: 12
  68. -- style flags: 0
  69. -- line height: 16
  70. -- part name: Install Menu
  71. ----- HyperTalk script -----
  72. on mouseUp
  73.   global ExampleMenu
  74.   if the short name of me is "Install Menu" then
  75.     InstallMenu -- see card script
  76.     set the name of me to "Remove Menu"
  77.   else
  78.     RemoveMenu -- see card script
  79.     set the name of me to "Install Menu"
  80.   end if
  81. end mouseUp
  82.  
  83.  
  84.  
  85. -- part 5 (field)
  86. -- low flags: 01
  87. -- high flags: 2007
  88. -- rect: left=18 top=32 right=288 bottom=480
  89. -- title width / last selected line: 0
  90. -- icon id / first selected line: 0 / 0
  91. -- text alignment: 0
  92. -- font id: 3
  93. -- text size: 10
  94. -- style flags: 0
  95. -- line height: 13
  96. -- part name: Documentation
  97.  
  98.  
  99. -- part 6 (button)
  100. -- low flags: 00
  101. -- high flags: A003
  102. -- rect: left=284 top=298 right=320 bottom=453
  103. -- title width / last selected line: 0
  104. -- icon id / first selected line: 0 / 0
  105. -- text alignment: 1
  106. -- font id: 0
  107. -- text size: 12
  108. -- style flags: 0
  109. -- line height: 16
  110. -- part name: Show LSC Source: part 1
  111. ----- HyperTalk script -----
  112. on mouseUp
  113.   if the short name of me is "Show LSC Source: part 1" then
  114.     set the visible of card field "source1" to true
  115.     set the visible of card field "source2" to false
  116.     set the name of me to "Show LSC Source: part 2"
  117.   else if the short name of me is "Show LSC Source: part 2" then
  118.     set the visible of card field "source2" to true
  119.     set the visible of card field "source1" to false
  120.     set the name of me to "Hide LSC Source"
  121.   else
  122.     set the visible of card field "source2" to false
  123.     set the visible of card field "source1" to false
  124.     set the name of me to "Show LSC Source: part 1"
  125.   end if
  126. end mouseUp
  127.  
  128.  
  129.  
  130. -- part 7 (field)
  131. -- low flags: 81
  132. -- high flags: 0007
  133. -- rect: left=18 top=31 right=289 bottom=492
  134. -- title width / last selected line: 0
  135. -- icon id / first selected line: 0 / 0
  136. -- text alignment: 0
  137. -- font id: 3
  138. -- text size: 10
  139. -- style flags: 0
  140. -- line height: 13
  141. -- part name: source1
  142.  
  143.  
  144. -- part 8 (field)
  145. -- low flags: 81
  146. -- high flags: 0007
  147. -- rect: left=18 top=31 right=289 bottom=492
  148. -- title width / last selected line: 0
  149. -- icon id / first selected line: 0 / 0
  150. -- text alignment: 0
  151. -- font id: 3
  152. -- text size: 10
  153. -- style flags: 0
  154. -- line height: 13
  155. -- part name: source2
  156.  
  157.  
  158. -- part contents for card part 5
  159. ----- text -----
  160. MenuHandler version 1.2d6
  161. Roger Brown
  162.  
  163. MenuHandler is an XCMD that gives you the ability to add and manipulate your own menus in a HyperCard stack.  You can add and delete whole menus and items from menus. You can set and unset check marks. You can change the names of HyperCard's menus and items in them, but this is not advised because HyperCard handles its own menus in a special way.  You can, however, hide HyperCard's menus or disable items in them using some features of this XCMD. 
  164.  
  165. To use this XCMD you will have to install your own DoMenu handler and maintain some special globals. These are explained below.
  166.  
  167. Note: This version does not support hierarchical menus.
  168. Warning: Does not work with menu patches for large Radius screens.
  169.  
  170. INVOKING MENUHANDLER
  171.  
  172.   HyperCard Syntax is:
  173.    
  174.           MenuHandler opcode,title,other things according to  opcode
  175.    
  176.     it returns:     error messages
  177.    
  178.    where    the opcodes are:
  179.                         
  180.                  Add - adds a new menu
  181.                            parameters are title,item string,before 
  182.                            title is the menu title
  183.                            items is string containing the menu items and their
  184.                                   states in the normal Mac ToolBox format except 
  185.                                   for commas instead of semi-colons to make 
  186.                                   hypertalk level processing easier
  187.                            before is a string that names a menu to insert this
  188.                                   one before (if empty, this menu goes at the
  189.                                   end of the menu bar)
  190.                 Delete - deletes a menu and its handle
  191.                            parameter is title
  192.                 Hide - hides a menu but remembers it for later restoration
  193.                            parameter is title
  194.                 Show - restores a hidden menu
  195.                            parameter is title,afterMenu
  196.                            where after menu can be specified or the default is
  197.                            its original position
  198.                 Insert - inserts a menu item
  199.                           parameters are menu title, item name with format
  200.                           specifications, after item (number or name)
  201.                 Remove - removes a menu item
  202.                           parameters are menu title, item name or number
  203.                 Enable - enables a menu item
  204.                           parameters are menu title, item name or number
  205.                           A number of 0 enables the whole menu
  206.                 Disable - disables a menu item
  207.                          parameters are menu title, item name or number
  208.                          A number of 0 disables the whole menu
  209.                 Mark - checks an item
  210.                          parameters are menu title, item name or number
  211.                          and mark: none,command,check,diamond, or apple
  212.                                                            
  213.       To compile: create a project with this and MacTraps. Build as code       
  214.                           resource type XCMD named MenuHandler.
  215.  
  216. EXAMPLE
  217.  
  218.  ex.  MenuHandler "Add","Help","Introduction,(----,Glossary"
  219.   
  220. SPECIAL GLOBALS
  221.  
  222.       A HyperCard global is maintained for every menu added through
  223.       MenuHandler. The global has the same name as the menu.
  224.       The menu items in a menu are found in a HyperCard item list
  225.       contained in a  global whose name is the name of the menu
  226.       concatenated with the word "Menu" . This makes it 
  227.       easy to test if a  doMenu call is for an added menu.
  228.       
  229.        ex. global HelpMenu = "Introduction,Getting Started,Glossary"
  230.       
  231.       An extra global is maintained that includes a list of all items
  232.       that are currently disabled. These can be in new menus or in
  233.       HyperCard's menus. This list is needed because some HyperCard
  234.       menu actions can still proceed even when their menu items appear
  235.       to be disabled.   
  236.  
  237. DOMENU HANDLER
  238.  
  239.       To use MenuHandler, you need to have your own DoMenu       
  240.       handler to see if the menu action is one of your own.  If it isn't
  241.       then you pass it on to HyperCard.  Another reason to have your
  242.       own DoMenu handler is to catch HyperCard menu items that you
  243.       want to be disabled because HyperCard doesn't pay any attention
  244.       to you if you make one of its items look disabled.  A sample
  245.       DoMenu handler is shown here and another is in the script of this
  246.       stack.
  247.  
  248.       example:
  249.  
  250.       on domenu anItem
  251.          global HelpMenu, Disabled
  252.          --anItem is the name of the menu item choosen
  253.          -- HelpMenu is a list of items in my own help menu
  254.          -- Disabled is the list of items that I have disabled
  255.          if Disabled contains anItem then
  256.            answer "HyperCard menu item "&anItem&" is disabled"┬¼
  257.            with "OK"
  258.            exit domenu
  259.          else if HelpMenu contains anItem then
  260.              DoMyHelp anItem -- see which item it is and do something
  261.          else   -- is an enable HyperCard item
  262.              pass domenu - pass it on down the line 
  263.              exit domenu
  264.         end if
  265.      end domenu
  266.  
  267. REVISION HISTORY
  268. 1.2d3 first public release version
  269. 1.2d4 fix problem with empty item list in AddAMenu
  270. 1.2d6 allow arbitrarily long menus in AddAMenu and InsertMenuItem
  271.  
  272.  
  273. -- part contents for card part 7
  274. ----- text -----
  275. /* MenuHandler1.2d6.c */
  276. /* ┬⌐ Trustees of Dartmouth College */
  277. /* written in LightSpeed C  ┬⌐ Think Technologies, Inc */
  278. /* by Roger Brown 7/21/88  Courseware Development group */
  279.  
  280. /* 5/5/89 version 1.2d6: Now handles arbitrarily long menu item lists in AddAMenu 
  281.    and InsertMenuItem. */
  282. /* version 1.2d4 will bomb if you insert enough items to make the item list global
  283.    greater than 255 chars.  The Menu Manager dosen't care, just my UpdateItemGlobal
  284.    procedure. */
  285. /* 5/5/89 version 1.2d4: fix empty list problem in AddAMenu */
  286.  
  287. /* This is a HyperCard XFCN that handles menus in all sorts of ways.
  288.   
  289.   *********************************
  290.   *** Requires HC v1.2 or later *** 
  291.   *********************************
  292.   
  293.   HyperCards Syntax is:
  294.    
  295.                 MenuHandler message,title,other things according to message
  296.    
  297.    ex.  MenuHandler "Add","Help","Introduction,(----,Glossary"
  298.   
  299.    returns:     error messages
  300.    
  301.    where    message is one of these opcodes:
  302.                                 Add - adds a new menu
  303.                                         parameters are title,item string,before 
  304.                                         title is the menu title
  305.                         items is string containing the menu items and their
  306.                                   states in the normal Mac ToolBox format except 
  307.                                   for commas instead of semi-colons to make 
  308.                                   hypertalk level processing easier
  309.                         before is a string that names a menu to insert this
  310.                                   one before (if empty, this menu goes at the
  311.                                   end of the menu bar)
  312.                 Delete - deletes a menu and its handle
  313.                      parameter is title
  314.                 Hide - hides a menu but remembers it for later restoration
  315.                      parameter is title
  316.                 Show - restores a hidden menu
  317.                      parameter is title,afterMenu
  318.                      where after menu can be specified or the default is
  319.                      its original position
  320.                 Insert - inserts a menu item
  321.                      parameters are menu title, item name with format
  322.                      specifications, after item (number or name)
  323.                 Remove - removes a menu item
  324.                      parameters are menu title, item name or number
  325.                 Enable - enables a menu item
  326.                      parameters are menu title, item name or number
  327.                      A number of 0 enables the whole menu
  328.                 Disable - disables a menu item
  329.                          parameters are menu title, item name or number
  330.                      A number of 0 disables the whole menu
  331.                 Mark - checks an item
  332.                      parameters are menu title, item name or number
  333.                      and mark: none,command,check,diamond, or apple
  334.                              
  335.          
  336.       A HyperCard global is maintained for every menu added through
  337.       MenuHandler. The menu items in a menu are found in a HyerCard item
  338.       list in the global with the menu's name. This makes it easy to 
  339.       test if a doMenu call is for an added menu.
  340.       
  341.       ex. global HelpMenu = "Introduction,Getting Started,Glossary"
  342.       
  343.       An extra global is maintained that includes a list of all items
  344.       that are currently disabled. These can be in new menus or in
  345.       HyperCard's menus. This list is needed because some HyperCard
  346.       menu actions can still proceed even when their menu items appear
  347.       to be disabled.   
  348.                          
  349.       To compile: create a project with this and MacTraps. Build as code resource type
  350.           XFCN named MenuHandler.
  351. */
  352.  
  353. #include "stddata_ctype.c"
  354. #include "strings.c"
  355. #include "MenuMgr.h"
  356. #include "HyperXCmd.h"
  357. #include "XCmdGlue.inc.c"
  358. #include "SetUpA4.h"
  359.  
  360. #define FALSE 0
  361. #define TRUE !FALSE
  362.  
  363.  
  364. typedef struct MenuRec {
  365.         MenuHandle menuOH;
  366.         int menuLeft;
  367. } MenuRec;
  368.  
  369. typedef struct DynamicMenuList {   /* this is actually a dynamic structure */
  370.         int lastMenu;
  371.         int lastRight;
  372.         int mbResID;
  373.         MenuRec menu[64];    /* 64 is an aribtrary number, but plenty big */
  374. } DynamicMenuList,*DMLPtr,**DMLHandle;
  375.  
  376. char isNumber();
  377. long ItemNumber();
  378. MenuHandle GetHiddenMenu();
  379.  
  380.  
  381. /* build a return result structure from a string */
  382.  
  383. ResultIs(paramPtr,theResult)
  384. XCmdBlockPtr    paramPtr;
  385. char *theResult;
  386. {
  387.         long len;
  388.         Handle resultHandle;
  389.         len = 1+strlen(theResult);
  390.         resultHandle = NewHandle(len);
  391.         BlockMove(theResult,*resultHandle,len);
  392.         paramPtr->returnValue = resultHandle;
  393. }
  394.  
  395. /* change a character into its upper case equivalent */
  396.  
  397. int     toupper(c)
  398. char    c;
  399. {
  400.         return( (c>='a')&&(c<='z') ? (c-('a'-'A')) : c );
  401. }
  402.  
  403. /* change a string into its upper case equivalent */
  404.  
  405. ucase(s)
  406. char *s;
  407. {
  408.         int i;
  409.         char c;
  410.         
  411.         for (i=0;i<strlen(s);i++) {
  412.                 s[i] = toupper(s[i]);
  413.         }
  414. }
  415.  
  416. /* Get the number of HyperCard comma delimited items in string s. */
  417.  
  418. int NumHCItems(s)
  419. char *s;
  420. {
  421.         int c,len,count,j;
  422.         char temp[255];
  423.         long it;
  424.         
  425.         count = j = 0;
  426.         len = strlen(s);
  427.         for (c=0;c<len;c++) {
  428.                 if (s[c]==',') {
  429.                         count = count + 1;
  430.                         j = 0;
  431.                 }
  432.                 else {
  433.                         temp[j] = s[c];
  434.                         j++;
  435.                         if (c==(len-1)) { /* last item, no comma */
  436.                                 count = count+1;
  437.                                 break;
  438.                         }
  439.                 }
  440.         }
  441.         return count;
  442. }
  443.  
  444. /* Get the number of HyperCard lines in string s. */
  445.  
  446. NumHCLines(source) 
  447. char *source;
  448. {
  449.         int i,c,len;
  450.         
  451.         len = strlen(source);
  452.         c = 0;
  453.         for (i=0;i<len;i++) {          
  454.                 if (source[i]==13) c++;
  455.         }
  456.         if (source[i-1]!=13) c++;          /* last line might not have CR */
  457.         return c;
  458. }
  459.  
  460. /* Get HyperCard comma delimited item i from item list string inStr. 
  461.    Return it in outStr */
  462.  
  463. GetHCItem(inStr,i,outStr)
  464. char *inStr,*outStr;
  465. int i;
  466. {
  467.         int c,len,count,j;
  468.         char temp[255];
  469.         
  470.         count = j = 0;
  471.         len = strlen(inStr);
  472.         for (c=0;c<len;c++) {
  473.                 if (inStr[c]==',') {
  474.                         count = count + 1;
  475.                         if (count==i) break;
  476.                         j = 0;
  477.                 }
  478.                 else {
  479.                         temp[j] = inStr[c];
  480.                         j++;
  481.                         if (c==(len-1)) { /* last item, no comma */
  482.                                 count = count+1;
  483.                                 break;
  484.                         }
  485.                 }
  486.         }
  487.         if (count < i) strcpy(temp,"");  /* no item there */
  488.         temp[j] = 0;
  489.         strcpy(outStr,temp);
  490.         return;
  491. }
  492.  
  493. /* get line number 'line' from source and return in dest */
  494.  
  495. GetHCLine(line,source,dest)
  496. int line;
  497. char *source,*dest;
  498. {
  499.         int i,j,c,len;
  500.  
  501.         len = strlen(source);
  502.         c = 1;
  503.         i = 0;
  504.         while (c<line) {
  505.                 if (source[i]==13) c++;
  506.                 i++;
  507.                 if (i>len) {     /* out of range */
  508.                         strcpy(dest,"");
  509.                         return;
  510.                 }
  511.         }
  512.         c = 0;
  513.         for (j=i;j<len;j++) {
  514.                 *(dest+c) = source[j];
  515.                 if (source[j]==13) break;    /* line ended */
  516.                 c++;
  517.         }
  518.         *(dest+c) = (char)0;
  519. }
  520.  
  521. /* Test if item in itemStr is in container */
  522.  
  523. ItemInContainer(itemStr,container)
  524. char *itemStr,*container;
  525. {
  526.         int c,len,j;
  527.         char temp[255];
  528.         
  529.         j = 0;
  530.         len = strlen(container);
  531.         for (c=0;c<len;c++) {
  532.                 if (container[c]==',') {
  533.                         if (strcmp(itemStr,temp)==0) return TRUE;
  534.                         j = 0;
  535.                 }
  536.                 else {
  537.                         temp[j] = container[c];
  538.                         j++;
  539.                         temp[j] = 0;
  540.                         if (c==(len-1)) { /* last item, no comma */
  541.                                 break;
  542.                         }
  543.                 }
  544.         }
  545.         temp[j] = 0;
  546.         if (strcmp(itemStr,temp)==0) return TRUE;
  547.         return FALSE;
  548.  
  549. }
  550.  
  551. /* return false if s is not a valid integer, true and number if it is */
  552.  
  553. char isNumber(s,num)
  554. char *s;
  555. long *num;
  556. {
  557.         /* s enters and exits in C format */
  558.         Str255 temp;
  559.         int i,len;
  560.         
  561.         /* see if all characters are digits */
  562.         len = strlen(s);
  563.         for (i=0;i<len;i++) {
  564.                 if (!isdigit(s[i])) return FALSE;
  565.         }
  566.         CtoPstr((char *)s);
  567.         StringToNum(s,num);
  568.         PtoCstr((char *)s);
  569.         return TRUE; 
  570. }
  571.  
  572.  
  573. /* Get the id of menu with title name. Also return its position in the
  574.    menu list */
  575.    
  576. GetMenuID(name,pos)
  577. char *name;
  578. int *pos;                   /* position in menu list */
  579. {
  580.         DMLHandle theList;
  581.         int lastMenu,i,j,numMenus;
  582.         MenuRec anEntry;
  583.         MenuHandle MHandle;
  584.         Ptr MPtr;
  585.         int *idPtr;
  586.         Str255 title,uName;
  587.         char len;
  588.         
  589.         strcpy(uName,name);     /* copy name and change it to upper case */
  590.         ucase(name);
  591.         theList = (DMLHandle)GetMenuBar();   /* get the menu list */
  592.         HLock((Handle)theList);
  593.         lastMenu = (**theList).lastMenu;
  594.         numMenus = lastMenu/6;
  595.         for (i=0;i<numMenus;i++) {            /* look at each menu in the list */
  596.                 anEntry = (**theList).menu[i];
  597.                 MHandle = anEntry.menuOH;
  598.                 MPtr = (Ptr)*MHandle;
  599.                 len = *(MPtr+14);
  600.                 for (j=0;j<len;j++) {             /* get its title */
  601.                         title[j] = *(MPtr+15+j);
  602.                 }
  603.                 title[j] = 0;
  604.                 ucase(title);
  605.                 if (strcmp(title,name)==0){        /* is it the same as name? */
  606.                         idPtr = (int*)MPtr;
  607.                         HUnlock(theList);
  608.                         *pos = i+1;
  609.                         return *idPtr;                 /* return its id and position */
  610.                 }
  611.         }
  612.         HUnlock(theList);
  613.         return 0;                              /* not found */
  614. }
  615.  
  616. /* get item number of an item, given its name */
  617.  
  618. long ItemNumber(theMenu,theItem)
  619. MenuHandle theMenu;
  620. char *theItem;
  621. {
  622.         int i,num;
  623.         Str255 temp;
  624.         
  625.         ucase(theItem);
  626.         num = 1+CountMItems(theMenu);
  627.         for (i=1;i<num;i++) {               /* scan all items in the menu */
  628.                 GetItem(theMenu,i,temp);
  629.                 ucase(temp);
  630.                 PtoCstr((char *)temp);
  631.                 if (strcmp(temp,theItem)==0)     /* found it */
  632.                         return (long)i;
  633.         }
  634.         return (long)0;                    /* not found */
  635. }
  636.  
  637.  
  638. /* Make the menus item list global agree with the menu. This completely
  639.    rebuilds the global. */
  640.  
  641. UpdateItemGlobal(paramPtr,title)
  642. XCmdBlockPtr    paramPtr;
  643. char *title;
  644. {
  645.         #define kBlockSize 255
  646.         Str255 name,temp;
  647.         int menuID,i,num;
  648.         MenuHandle theMenu;
  649.         long dummy,len;
  650.         Handle theList;
  651.         
  652.         menuID = GetMenuID(title,&dummy);
  653.         theMenu = GetMHandle(menuID);
  654.         strcpy(name,title);
  655.         strcat(name,"Menu");
  656.         CtoPstr((char *)name);
  657.         theList = NewHandle(kBlockSize);
  658.         if (theList == NULL) {
  659.                 ResultIs(paramPtr,"Out of memory in MenuHandler XCMD");
  660.                 return;
  661.         }
  662.         HLock(theList);
  663.         **theList = 0;
  664.         len = kBlockSize;
  665.         
  666.         /* scan the menu list and pick up all item names */
  667.         
  668.         num = 1+CountMItems(theMenu);
  669.         for (i=1;i<num;i++) {
  670.                 GetItem(theMenu,i,temp);
  671.                 ucase(temp);
  672.                 PtoCstr((char *)temp);
  673.                 if (strlen(*theList)+strlen(temp) > len) {   /* open up the list global */
  674.                         len = len + kBlockSize;
  675.                         HUnlock(theList);
  676.                         SetHandleSize(theList,len);
  677.                         if (MemError()!=noErr) {
  678.                                 ResultIs(paramPtr,"Out of memory in MenuHandler XCMD");
  679.                                 DisposHandle(theList);
  680.                                 return;
  681.                         }
  682.                         HLock(theList);
  683.                 }
  684.                 strcat(*theList,temp);
  685.                 if (i<num-1) strcat(*theList,",");
  686.         }
  687.         
  688.         SetGlobal(paramPtr,name,theList);
  689.         DisposHandle(theList);
  690. }
  691.  
  692.  
  693. /* remove a menu from the disable global */
  694.  
  695. RemoveFromDisableGlobal(paramPtr,theMenu,theItem)
  696. XCmdBlockPtr    paramPtr;
  697. MenuHandle theMenu;
  698. int theItem;
  699. {
  700.         Handle theGlobal,theNewGlobal;
  701.         int i,numItems;
  702.         Str255 temp,itemName,handleStr;
  703.         long len,tempLong;
  704.                 
  705.         GetItem(theMenu,theItem,itemName);
  706.         
  707.         PtoCstr((char *)itemName);
  708.         theGlobal = GetGlobal(paramPtr,"\pdisabled");
  709.         theNewGlobal = NewHandle(1);
  710.         if (MemError()!=noErr) {
  711.                 ResultIs(paramPtr,"Out of Memory");
  712.                 return;
  713.         }
  714.         MoveHHi(theGlobal);
  715.         HLock(theGlobal);
  716.         (**theNewGlobal) = 0;
  717.         MoveHHi(theNewGlobal);
  718.         HLock(theNewGlobal);
  719.         strcpy(*theNewGlobal,"");
  720.         
  721.         /* scan the current global and rebuild  with everything but this one */
  722.         
  723.         numItems = NumHCItems(*theGlobal);
  724.         for (i=0;i<numItems;i++) {
  725.                 GetHCItem(*theGlobal,i+1,temp);
  726.                  if (strcmp(itemName,temp)!=0) {   /* not this one, put it back */
  727.                         strcat(temp,",");
  728.                         len = GetHandleSize(theNewGlobal);
  729.                         len = len + (long)strlen(temp);
  730.                         HUnlock(theNewGlobal);
  731.                         SetHandleSize(theNewGlobal,len);
  732.                         if (MemError()!=noErr) {
  733.                                 ResultIs(paramPtr,"Out of Memory");
  734.                                 return;
  735.                         }
  736.                         HLock(theNewGlobal);
  737.                         /* check for errors? */
  738.                         strcat(*theNewGlobal,temp);
  739.                 }
  740.         }
  741.         
  742.         /* set the new global value */
  743.         
  744.         SetGlobal(paramPtr,"\pdisabled",theNewGlobal);
  745.         HUnlock(theGlobal);
  746.         HUnlock(theNewGlobal);
  747.         DisposHandle(theGlobal);
  748.         DisposHandle(theNewGlobal);
  749. }
  750.  
  751. /* add a menu to the disable global */
  752.  
  753. AddToDisableGlobal(paramPtr,theMenu,theItem)
  754. XCmdBlockPtr    paramPtr;
  755. MenuHandle theMenu;
  756. int theItem;
  757. {
  758.         Handle theGlobal;
  759.         Str255 numStr,temp,itemName;
  760.         long len,tempLong;
  761.  
  762.         GetItem(theMenu,theItem,itemName);
  763.         PtoCstr((char *)itemName);
  764.         theGlobal = GetGlobal(paramPtr,"\pdisabled");
  765.         HLock(theGlobal);
  766.         
  767.         /* see if its already there */
  768.         
  769.         if (ItemInContainer(itemName,*theGlobal)) {   /* already stored */
  770.                 HUnlock(theGlobal);
  771.                 DisposHandle(theGlobal);
  772.                 return;
  773.         }
  774.         
  775.         /* tack it on the end */
  776.         len = GetHandleSize(theGlobal);
  777.         len = len + (long)strlen(itemName) + 2;
  778.         HUnlock(theGlobal);
  779.         SetHandleSize(theGlobal,len);
  780.         if (MemError()!=noErr) {
  781.                 ResultIs(paramPtr,"Out of Memory");
  782.                 DisposHandle(theGlobal);
  783.                 return;
  784.         }
  785.         HLock(theGlobal);
  786.         strcat(*theGlobal,itemName);
  787.         strcat(*theGlobal,",");
  788.         HUnlock(theGlobal);
  789.         SetGlobal(paramPtr,"\pdisabled",theGlobal);
  790.         DisposHandle(theGlobal);
  791. }
  792.  
  793.  
  794. /* add a menu to the menu bar */
  795.  
  796. pascal void AddAMenu(paramPtr)
  797. XCmdBlockPtr    paramPtr;
  798. {   
  799.         int i,itsID,itemCount;
  800.         Str255 titleStr,itemStr,beforeStr;
  801.         Ptr theTitle,theItems;
  802.         MenuHandle theMenu;
  803.         int theMenuID,pos,beforeID;
  804.         
  805.         /* check parameter count */
  806.         
  807.         if (paramPtr->paramCount < 3) {
  808.                 ResultIs(paramPtr,"Not enough parameters in Add.");
  809.                 return;
  810.         }
  811.  
  812.         /* lock down the parameters so we can point to them */
  813.         
  814.         for (i=1;i<paramPtr->paramCount;i++) {
  815.                 MoveHHi(paramPtr->params[i]);
  816.                 HLock (paramPtr->params[i]);
  817.         }
  818.         
  819.         /* get the parameters */
  820.         
  821.         theTitle = *(paramPtr->params[1]);
  822.         theItems = *(paramPtr->params[2]);
  823.         strcpy(titleStr,theTitle);
  824.                 
  825.         /* see if we really need to do this */
  826.         
  827.         if (GetMenuID(theTitle,&pos)!=0) {
  828.                 ResultIs(paramPtr,"Menu already shown.");
  829.                 for (i=1;i<paramPtr->paramCount;i++) 
  830.                         HUnlock (paramPtr->params[i]);
  831.                 return;
  832.         }
  833.         
  834.         /* get ready to talk to the menu manager */
  835.         
  836.         CtoPstr((char *)titleStr);
  837.         
  838.         /* get an id for this menu */
  839.         
  840.         itsID = 0;
  841.         while (itsID<128)
  842.                 itsID = UniqueID('MENU');
  843.                 
  844.         /* create the menu and insert the items */
  845.         
  846.         theMenu = NewMenu(itsID,titleStr);
  847.         strcpy(itemStr," ");            /* create menu with 1 blank item cuz AppendMenu */
  848.         CtoPstr((char*)itemStr);
  849.         AppendMenu(theMenu,itemStr);    /* can't handle a null string */
  850.         DelMenuItem(theMenu,1);         /* now get rid of the blank menu item */
  851.  
  852.         /* add all items by inserting - so we aren't constrained to 255 char limit */
  853.         itemCount = NumHCItems(theItems);
  854.         for (i=0;i<itemCount;i++) {
  855.                 GetHCItem(theItems,i+1,itemStr);
  856.                 CtoPstr((char *)itemStr);
  857.                 InsMenuItem(theMenu,itemStr,i+2);
  858.         }
  859.  
  860.         /* insert it as requested */
  861.         
  862.         beforeID = 0;
  863.         if (paramPtr->paramCount > 3) {
  864.                 strcpy(beforeStr,*(paramPtr->params[3]));
  865.                 beforeID = GetMenuID(beforeStr,&pos);
  866.         }
  867.         InsertMenu(theMenu,beforeID);
  868.         
  869.         /* update the menu bar */
  870.         
  871.         DrawMenuBar();
  872.         
  873.         /* create the menu global */
  874.         
  875.         PtoCstr((char *)titleStr);
  876.         UpdateItemGlobal(paramPtr,titleStr);
  877.  
  878.         /* clean up */
  879.         
  880.         for (i=1;i<paramPtr->paramCount;i++) HUnlock (paramPtr->params[i]);
  881.         
  882.         return;
  883. }
  884.  
  885. /* delete a menu from the menu bar and remove it from memory */
  886.  
  887. pascal void DeleteAMenu(paramPtr)
  888. XCmdBlockPtr    paramPtr;
  889. {   
  890.         int i,itsID;
  891.         Str255 titleStr,itemStr;
  892.         Ptr theTitle,theItems;
  893.         MenuHandle theMenu;
  894.         int theMenuID,pos;
  895.         Handle empty;
  896.         
  897.         /* check parameter count */
  898.         
  899.         if (paramPtr->paramCount < 2) {
  900.                 ResultIs(paramPtr,"Not enough parameters in Delete.");
  901.                 return;
  902.         }
  903.  
  904.         /* lock parameters down so we can point to them */
  905.         
  906.         MoveHHi(paramPtr->params[1]);
  907.         HLock (paramPtr->params[1]);
  908.         
  909.         theTitle = *(paramPtr->params[1]);
  910.         strcpy(titleStr,theTitle);
  911.         
  912.         /* get the id of this menu */
  913.         
  914.         theMenuID = GetMenuID(titleStr,&pos);
  915.         if (theMenuID==NULL) {
  916.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu to delete");
  917.                 }
  918.         else {
  919.                 /* get the menu and do the delete */
  920.                 
  921.                 theMenu = GetMHandle(theMenuID);
  922.                         
  923.                 /* delete it from out save list if it is there */
  924.                 
  925.                 RemoveFromSaveList(paramPtr,theMenu);
  926.                 
  927.                 /* remove its items from the disabled list */
  928.                 
  929.                 for (i=0;i<CountMItems(theMenu);i++) 
  930.                         RemoveFromDisableGlobal(paramPtr,theMenu,i+1);
  931.                 
  932.                 DeleteMenu(theMenuID);
  933.                 DisposeMenu(theMenu);
  934.                 DrawMenuBar();
  935.                 
  936.                 /* clear the global with its name */
  937.                 CtoPstr((char *)titleStr);
  938.                 empty = NewHandle(1);
  939.                 if (MemError()!=noErr) {
  940.                         ResultIs(paramPtr,"Out of Memory");
  941.                         return;
  942.                 }
  943.                 HLock(empty);
  944.                 (**empty) = 0;
  945.                 HUnlock(empty);
  946.                 SetGlobal(paramPtr,titleStr,empty);
  947.                 DisposHandle(empty);
  948.         }
  949.         HUnlock (paramPtr->params[1]);
  950.         
  951.         return;
  952. }
  953.  
  954. /* store a menu title,id, and position in a hidden HyperCard global */
  955.  
  956. StoreHiddenMenu(paramPtr,title,theMenu,pos)
  957. XCmdBlockPtr    paramPtr;
  958. char *title;
  959. MenuHandle theMenu;
  960. int pos;
  961. {
  962.         Handle theGlobal;
  963.         Str255 numStr,temp;
  964.         long len,tempLong;
  965.         
  966.         if (GetHiddenMenu(paramPtr,title,&tempLong)!=NULL) {
  967.                 return;   /* already stored */
  968.         }
  969.         theGlobal = GetGlobal(paramPtr,"\pXXMHLISTXX");
  970.         HLock(theGlobal);
  971.         NumToString(theMenu,numStr);           /* the menu handle */
  972.         PtoCstr((char *)numStr);
  973.         strcpy(temp,title);                    /* the menu title */
  974.         strcat(temp,",");
  975.         strcat(temp,numStr);
  976.         strcat(temp,",");
  977.         NumToString((long)pos,numStr);       /* its position in the menu list */
  978.         PtoCstr((char *)numStr);
  979.         strcat(temp,numStr);
  980.         strcat(temp,"\15");                  /* make it a HyperCard line */
  981.         
  982.         /* add it to the end of the existing global */
  983.         
  984.         len = GetHandleSize(theGlobal) + (long)strlen(temp) + 1;
  985.         HUnlock(theGlobal);
  986.         SetHandleSize(theGlobal,len);
  987.         if (MemError()!=noErr) {
  988.                 ResultIs(paramPtr,"Out of Memory");
  989.                 DisposHandle(theGlobal);
  990.                 return;
  991.         }
  992.         HLock(theGlobal);
  993.         strcat(*theGlobal,temp);
  994.         HUnlock(theGlobal);
  995.         SetGlobal(paramPtr,"\pXXMHLISTXX",theGlobal);
  996.         DisposHandle(theGlobal);
  997. }
  998.  
  999.  
  1000. /* get a hidden menu's id from the hidden HC global. Return its handle
  1001.    and its position in the hidden list */
  1002.  
  1003. MenuHandle GetHiddenMenu(paramPtr,title,pos)
  1004. XCmdBlockPtr    paramPtr;
  1005. char *title;
  1006. long *pos;
  1007. {
  1008.         Handle theGlobal;
  1009.         MenuHandle theMenu;
  1010.         int i,numLines;
  1011.         Str255 temp,name,idStr;
  1012.         
  1013.         /* get the hidden menu list */
  1014.         
  1015.         theGlobal = GetGlobal(paramPtr,"\pXXMHLISTXX");
  1016.         HLock(theGlobal);
  1017.         numLines = NumHCLines(*theGlobal);
  1018.         
  1019.         /* find it in the list */
  1020.         
  1021.         for (i=0;i<numLines;i++) {
  1022.                 GetHCLine(i+1,*theGlobal,temp); /* get the line for this menu */
  1023.                 GetHCItem(temp,1,name);
  1024.          if (strcmp(name,title)==0) {
  1025.                         GetHCItem(temp,2,idStr);    /* get its handle */
  1026.                         CtoPstr((char *)idStr);
  1027.                         StringToNum(idStr,&theMenu);
  1028.                         GetHCItem(temp,3,idStr);    /* and its position */
  1029.                         CtoPstr((char *)idStr);
  1030.                         StringToNum(idStr,pos);
  1031.                         HUnlock(theGlobal);
  1032.                         DisposHandle(theGlobal);
  1033.                         return theMenu;
  1034.                 }
  1035.         }
  1036.         HUnlock(theGlobal);
  1037.         DisposHandle(theGlobal);
  1038.         return NULL;
  1039. }
  1040.  
  1041. /* remove a menu from the list of saved menus */
  1042.  
  1043. RemoveFromSaveList(paramPtr,itsHandle)
  1044. XCmdBlockPtr    paramPtr;
  1045. Handle itsHandle;
  1046. {
  1047.         Handle theGlobal,theNewGlobal;
  1048.         MenuHandle theMenu;
  1049.         int i,numLines;
  1050.         Str255 temp,itemStr,handleStr;
  1051.         long len;
  1052.         
  1053.         /* scan the global and rebuild with all parts except this one */
  1054.         
  1055.         theGlobal = GetGlobal(paramPtr,"\pXXMHLISTXX");
  1056.         theNewGlobal = NewHandle(1);
  1057.         if (MemError()!=noErr) {
  1058.                 ResultIs(paramPtr,"Out of Memory");
  1059.                 return;
  1060.         }
  1061.         HLock(theGlobal);
  1062.         HLock(theNewGlobal);
  1063.         strcpy(*theNewGlobal,"");
  1064.         NumToString((long)itsHandle,handleStr);
  1065.         PtoCstr((char *)handleStr);
  1066.         numLines = NumHCLines(*theGlobal);
  1067.         for (i=0;i<numLines;i++) {
  1068.                 GetHCLine(i+1,*theGlobal,temp);
  1069.                 GetHCItem(temp,2,itemStr);
  1070.                  if (strcmp(itemStr,handleStr)!=0) {  /* not this one, put it back */
  1071.                 strcat(temp,"\15");
  1072.                         len = GetHandleSize(theNewGlobal) + (long)strlen(temp);
  1073.                         HUnlock(theNewGlobal);
  1074.                         SetHandleSize(theNewGlobal,len);
  1075.                         HLock(theNewGlobal);
  1076.                         /* check for errors? */
  1077.                         strcat(*theNewGlobal,temp);
  1078.                 }
  1079.         }
  1080.         SetGlobal(paramPtr,"\pXXMHLISTXX",theNewGlobal);
  1081.         HUnlock(theGlobal);
  1082.         HUnlock(theNewGlobal);
  1083.         DisposHandle(theGlobal);
  1084.         DisposHandle(theNewGlobal);
  1085. }
  1086.  
  1087.  
  1088.  
  1089. /* hide a menu but save it for later restoration */
  1090. /* store info in a special hypercard global */
  1091.  
  1092. pascal void HideMenu(paramPtr)
  1093. XCmdBlockPtr    paramPtr;
  1094. {   
  1095.         int i,itsID;
  1096.         Str255 titleStr,itemStr;
  1097.         Ptr theTitle,theItems;
  1098.         MenuHandle theMenu;
  1099.         int theMenuID,pos;
  1100.         
  1101.         /* check parameter count */
  1102.         
  1103.         if (paramPtr->paramCount < 2) {
  1104.                 ResultIs(paramPtr,"Not enough parameters in Hide.");
  1105.                 return;
  1106.         }
  1107.  
  1108.         /* lock the parameters down so we can point to them */
  1109.         
  1110.         MoveHHi(paramPtr->params[1]);
  1111.         HLock (paramPtr->params[1]);
  1112.         
  1113.         theTitle = *(paramPtr->params[1]);
  1114.         strcpy(titleStr,theTitle);
  1115.         theMenuID = GetMenuID(titleStr,&pos);
  1116.         if (theMenuID==NULL) 
  1117.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu to hide");
  1118.         else {
  1119.                 /* delete the menu from the menu list but remember its name,
  1120.                    handle and position */
  1121.                    
  1122.                 theMenu = GetMHandle(theMenuID);
  1123.                 DeleteMenu(theMenuID);
  1124.                 StoreHiddenMenu(paramPtr,titleStr,theMenu,pos);
  1125.                 DrawMenuBar();
  1126.         }
  1127.         HUnlock (paramPtr->params[1]);
  1128.         
  1129.         return;
  1130. }
  1131.  
  1132.  
  1133.  
  1134. -- part contents for card part 8
  1135. ----- text -----
  1136. /* MenuHandler source: part 2 */
  1137.  
  1138. /* show a hidden menu */
  1139.  
  1140. pascal void ShowMenu(paramPtr)
  1141. XCmdBlockPtr    paramPtr;
  1142. {   
  1143.         int i,itsID;
  1144.         Str255 titleStr,itemStr,posStr;
  1145.         Ptr theTitle;
  1146.         MenuHandle theMenu;
  1147.         int theMenuID;
  1148.         long pos;
  1149.         
  1150.         /* check parameter count */
  1151.         
  1152.         if (paramPtr->paramCount < 3) {
  1153.                 ResultIs(paramPtr,"Not enough parameters in Show.");
  1154.                 return;
  1155.         }
  1156.  
  1157.         /* lock parameters down so we can point to them */
  1158.         
  1159.         for (i=1;i<3;i++) {
  1160.                 MoveHHi(paramPtr->params[i]);
  1161.                 HLock (paramPtr->params[i]);
  1162.         }
  1163.         
  1164.         theTitle = *(paramPtr->params[1]);
  1165.         strcpy(titleStr,theTitle);
  1166.         ucase(titleStr);
  1167.         strcpy(posStr,*paramPtr->params[2]);
  1168.         
  1169.         /* find the menu in the hidden list */
  1170.         
  1171.         theMenu = GetHiddenMenu(paramPtr,titleStr,&pos);
  1172.         if (theMenu==NULL) 
  1173.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu to show");
  1174.         else {
  1175.                 /* get its position */
  1176.                 if (strcmp(posStr,"")!=0) {
  1177.                         if (!isNumber(posStr,&pos)) {
  1178.                                 pos = ItemNumber(theMenu,posStr);
  1179.                         }
  1180.                 }
  1181.                 /* move it from hidden to shown */
  1182.                 
  1183.                 InsertMenu(theMenu,(int)pos);   
  1184.                 RemoveFromSaveList(paramPtr,theMenu);
  1185.                 DrawMenuBar();
  1186.         }
  1187.         for (i=1;i<3;i++) 
  1188.                 HUnlock (paramPtr->params[i]);
  1189.         
  1190.         return;
  1191. }
  1192.  
  1193. /* insert an item into a menu */
  1194.  
  1195. pascal void InsertMenuItem(paramPtr)
  1196. XCmdBlockPtr    paramPtr;
  1197. {   
  1198.         int i,itsID,itemCount;
  1199.         Str255 titleStr,itemStr,afterStr;
  1200.         MenuHandle theMenu;
  1201.         int theMenuID,pos;
  1202.         long afterItem;
  1203.         Ptr theItems;
  1204.         
  1205.         /* check paramter count */
  1206.         
  1207.         if (paramPtr->paramCount < 4) {
  1208.                 ResultIs(paramPtr,"Not enough parameters in Insert.");
  1209.                 return;
  1210.         }
  1211.         
  1212.         /* lock paramters down so we can point to them */
  1213.         
  1214.         for (i=1;i<4;i++) {
  1215.                 MoveHHi(paramPtr->params[i]);
  1216.                 HLock (paramPtr->params[i]);
  1217.         }
  1218.         
  1219.         /* get the parameters */
  1220.         
  1221.         strcpy(titleStr,*(paramPtr->params[1]));
  1222.         theItems = *(paramPtr->params[2]);
  1223.         strcpy(afterStr,*(paramPtr->params[3]));
  1224.         
  1225.         /* get the menu */
  1226.         
  1227.         theMenuID = GetMenuID(titleStr,&pos);
  1228.         if (theMenuID==NULL) {
  1229.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu for insert");
  1230.         }
  1231.         else {
  1232.                 /* get its handle */
  1233.                 theMenu = GetMHandle(theMenuID);
  1234.                 CtoPstr((char *)itemStr);
  1235.                 
  1236.                 /* Is it identified by name or number? */
  1237.                 
  1238.                 if (!isNumber(afterStr,&afterItem))
  1239.                         afterItem = ItemNumber(theMenu,afterStr);
  1240.                                 
  1241.                 /* add all items by inserting - so we aren't constrained to 255 char limit */
  1242.                 itemCount = NumHCItems(theItems);
  1243.                 for (i=0;i<itemCount;i++) {
  1244.                         GetHCItem(theItems,i+1,itemStr);
  1245.                         CtoPstr((char *)itemStr);
  1246.                         InsMenuItem(theMenu,itemStr,(int)(afterItem+i+2));
  1247.                 }
  1248.  
  1249.                 
  1250.                 /* register this change in the menu global */
  1251.                 
  1252.                 UpdateItemGlobal(paramPtr,titleStr);
  1253.         }
  1254.         for (i=1;i<4;i++) HUnlock (paramPtr->params[i]);
  1255.  
  1256. }
  1257.  
  1258. /* remove an item from a menu */
  1259.  
  1260. pascal void RemoveMenuItem(paramPtr)
  1261. XCmdBlockPtr    paramPtr;
  1262. {  
  1263.         int i,itsID;
  1264.         Str255 titleStr,itemStr;
  1265.         Ptr theTitle,theItems;
  1266.         MenuHandle theMenu;
  1267.         int theMenuID;
  1268.         long theItem,pos;
  1269.         
  1270.         /* checkl parameter count */
  1271.         
  1272.         if (paramPtr->paramCount < 3) {
  1273.                 ResultIs(paramPtr,"Not enough parameters in Remove.");
  1274.                 return;
  1275.         }
  1276.  
  1277.         /* lock the parameters so we can point to them */
  1278.         
  1279.         for (i=1;i<3;i++) {
  1280.                 MoveHHi(paramPtr->params[i]);
  1281.                 HLock (paramPtr->params[i]);
  1282.         }
  1283.         
  1284.         /* get parameters */
  1285.         
  1286.         strcpy(titleStr,*(paramPtr->params[1]));
  1287.         strcpy(itemStr,*(paramPtr->params[2]));
  1288.         
  1289.         /* get the menu */
  1290.         
  1291.         theMenuID = GetMenuID(titleStr,&pos);
  1292.         if (theMenuID==NULL) 
  1293.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu for removal request");
  1294.         else {
  1295.                 /* get its handle */
  1296.                 
  1297.                 theMenu = GetMHandle(theMenuID);
  1298.                 
  1299.                 /* is it identified by name or number? */
  1300.                 if (!isNumber(itemStr,&theItem)) 
  1301.                         theItem = ItemNumber(theMenu,itemStr);
  1302.                         
  1303.             /* delete it and update the menu global */
  1304.             
  1305.                 DelMenuItem(theMenu,(int)theItem);
  1306.                 UpdateItemGlobal(paramPtr,titleStr);
  1307.                 
  1308.         }
  1309.         for (i=1;i<3;i++) HUnlock (paramPtr->params[i]);
  1310. }
  1311.  
  1312. /* enable an item in a menu */
  1313.  
  1314. pascal void EnableMenuItem(paramPtr)
  1315. XCmdBlockPtr    paramPtr;
  1316. {   
  1317.         int i,itsID;
  1318.         Str255 titleStr,itemStr;
  1319.         Ptr theTitle,theItems;
  1320.         MenuHandle theMenu;
  1321.         int theMenuID,pos;
  1322.         long theItem;
  1323.         
  1324.         /* check parameter count */
  1325.         
  1326.         if (paramPtr->paramCount < 3) {
  1327.                 ResultIs(paramPtr,"Not enough parameters in Enable.");
  1328.                 return;
  1329.         }
  1330.         
  1331.         /* lock down parameters so we can point to them */
  1332.         
  1333.         for (i=1;i<3;i++) {
  1334.                 MoveHHi(paramPtr->params[i]);
  1335.                 HLock (paramPtr->params[i]);
  1336.         }
  1337.         
  1338.         /* get parameters */
  1339.         
  1340.         strcpy(titleStr,*(paramPtr->params[1]));
  1341.         strcpy(itemStr,*(paramPtr->params[2]));
  1342.         
  1343.         
  1344.         /* get the menu */
  1345.         
  1346.         theMenuID = GetMenuID(titleStr,&pos);
  1347.         
  1348.         if (theMenuID==NULL) 
  1349.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu for enable request");
  1350.         else {
  1351.         
  1352.                 /* get its handle */
  1353.                 
  1354.                 theMenu = GetMHandle(theMenuID);
  1355.                 
  1356.                 /* is it identified by name or number? */
  1357.                 
  1358.                 if (!isNumber(itemStr,&theItem)) {
  1359.                         theItem = ItemNumber(theMenu,itemStr);
  1360.                         if (theItem==0L) {  /* none to disable */
  1361.                                 ResultIs(paramPtr,"Invalid item number in enable");
  1362.                         
  1363.                                 for (i=1;i<3;i++) HUnlock (paramPtr->params[i]);
  1364.                                 return;
  1365.                         }
  1366.                 }
  1367.                 EnableItem(theMenu,(int)theItem);
  1368.                 
  1369.                 if ((int)theItem != 0) {
  1370.                 
  1371.                         /* update disable global */
  1372.                 
  1373.                         RemoveFromDisableGlobal(paramPtr,theMenu,(int)theItem);
  1374.                 }
  1375.                 else {   /* remove all items in it from the disable global */
  1376.                         for (i=0;i<CountMItems(theMenu);i++) {
  1377.                                         RemoveFromDisableGlobal(paramPtr,theMenu,(int)i+1);
  1378.                         }
  1379.                 }
  1380.         }
  1381.         for (i=1;i<3;i++) HUnlock (paramPtr->params[i]);
  1382. }
  1383.  
  1384. /* disable a menu item  */
  1385.  
  1386. pascal void DisableMenuItem(paramPtr)
  1387. XCmdBlockPtr    paramPtr;
  1388. {   
  1389.         int i,itsID;
  1390.         Str255 titleStr,itemStr;
  1391.         Ptr theTitle,theItems;
  1392.         MenuHandle theMenu;
  1393.         int theMenuID,pos;
  1394.         long theItem;
  1395.         
  1396.         /* check parameter count */
  1397.         
  1398.         if (paramPtr->paramCount < 3) {
  1399.                 ResultIs(paramPtr,"Not enough parameters in Disable.");
  1400.                 return;
  1401.         }
  1402.         
  1403.         /* lock down parameters so we can point to them */
  1404.         
  1405.         for (i=1;i<3;i++) {
  1406.                 MoveHHi(paramPtr->params[i]);
  1407.                 HLock (paramPtr->params[i]);
  1408.         }
  1409.         
  1410.         /* get parameters */
  1411.         
  1412.         strcpy(titleStr,*(paramPtr->params[1]));
  1413.         strcpy(itemStr,*(paramPtr->params[2]));
  1414.         
  1415.         /* get the menu */
  1416.         
  1417.         theMenuID = GetMenuID(titleStr,&pos);
  1418.         
  1419.         if (theMenuID==NULL) 
  1420.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu for disable request");
  1421.         else {
  1422.                 /* get its handle */
  1423.                 theMenu = GetMHandle(theMenuID);
  1424.         
  1425.                 /* is it identified by name or number? */
  1426.                 
  1427.                 if (!isNumber(itemStr,&theItem)) {
  1428.                 
  1429.                         theItem = ItemNumber(theMenu,itemStr);
  1430.         
  1431.                         if (theItem==0L) {  /* none to disable */
  1432.                                 ResultIs(paramPtr,"Invalid item number in disable");
  1433.                         
  1434.                                 for (i=1;i<3;i++) HUnlock (paramPtr->params[i]);
  1435.                         
  1436.                                 return;
  1437.                         }
  1438.                 }
  1439.  
  1440.                 /* disable it */
  1441.                 
  1442.                 DisableItem(theMenu,(int)theItem);
  1443.                 
  1444.                 
  1445.         
  1446.                 /* update the disabled menu global */
  1447.                 
  1448.                 if ((int)theItem != 0) {
  1449.         
  1450.                         AddToDisableGlobal(paramPtr,theMenu,(int)theItem);
  1451.                 }
  1452.                 else {
  1453.                         for (i=0;i<CountMItems(theMenu);i++) {
  1454.                                                 AddToDisableGlobal(paramPtr,theMenu,(int)i+1);
  1455.                         }
  1456.                 }
  1457.         }
  1458.  
  1459.         for (i=1;i<3;i++) HUnlock (paramPtr->params[i]);
  1460.                 
  1461. }
  1462.  
  1463. /* mark a menu item  */
  1464.  
  1465. pascal void MarkMenuItem(paramPtr)
  1466. XCmdBlockPtr    paramPtr;
  1467. {   
  1468.         int i,itsID;
  1469.         Str255 titleStr,itemStr,markStr;
  1470.         Ptr theTitle,theItems;
  1471.         MenuHandle theMenu;
  1472.         int theMenuID,pos;
  1473.         long theItem;
  1474.         char markChar;
  1475.         
  1476.         /* checl parameter count */
  1477.         if (paramPtr->paramCount < 4) {
  1478.                 ResultIs(paramPtr,"Not enough parameters in Mark.");
  1479.                 return;
  1480.         }
  1481.         
  1482.         /* lock down the parameters so we can point to them */
  1483.         
  1484.         for (i=1;i<4;i++) {
  1485.                 MoveHHi(paramPtr->params[i]);
  1486.                 HLock (paramPtr->params[i]);
  1487.         }
  1488.         
  1489.         /* get parameters */
  1490.         
  1491.         strcpy(titleStr,*(paramPtr->params[1]));
  1492.         strcpy(itemStr,*(paramPtr->params[2]));
  1493.         
  1494.         /* get the menu */
  1495.         
  1496.         theMenuID = GetMenuID(titleStr,&pos);
  1497.         
  1498.         if (theMenuID==NULL) 
  1499.                 ResultIs(paramPtr,"MenuHandler error:Can't find menu for mark request");
  1500.         else {
  1501.                 /* get its handle */
  1502.                 theMenu = GetMHandle(theMenuID);
  1503.                 
  1504.                 /* is it identified by name or number? */
  1505.                 if (!isNumber(itemStr,&theItem)) {
  1506.                         theItem = ItemNumber(theMenu,itemStr);
  1507.                         if (theItem==0L) {  /* none to mark */
  1508.                                 ResultIs(paramPtr,"Invalid item number in mark");
  1509.                                 for (i=1;i<4;i++) HUnlock (paramPtr->params[i]);
  1510.                                 return;
  1511.                         }
  1512.                 }
  1513.                 
  1514.                 /* decode the mark parameter */
  1515.         strcpy(markStr,*(paramPtr->params[3]));
  1516.                 ucase(markStr);
  1517.                 if (strcmp(markStr,"NONE")==0) markChar = noMark;
  1518.                 else if (strcmp(markStr,"COMMAND")==0) markChar = commandMark;
  1519.                 else if (strcmp(markStr,"CHECK")==0) markChar = checkMark;
  1520.                 else if (strcmp(markStr,"DIAMOND")==0) markChar = diamondMark;
  1521.                 else if (strcmp(markStr,"APPLE")==0) markChar = appleMark;
  1522.                 else {
  1523.                         ResultIs(paramPtr,"Unknown mark type.");
  1524.                         return;
  1525.                 }
  1526.                 
  1527.                 /* set the mark */
  1528.                 
  1529.                 SetItemMark(theMenu,theItem,markChar);
  1530.                 
  1531.         }
  1532.  
  1533.         for (i=1;i<4;i++) HUnlock (paramPtr->params[i]);
  1534.                 
  1535. }
  1536.  
  1537. /* XCMD entry point */
  1538.  
  1539.  
  1540. pascal void main(paramPtr)
  1541. XCmdBlockPtr    paramPtr;
  1542. /* this is the entry point for the XFCN */
  1543. {
  1544.         Handle taskHandle,portHandle;
  1545.         Str255 temp;
  1546.         
  1547.         RememberA0();
  1548.         SetUpA4();              /* use global variables */
  1549.         
  1550.         /* get the opcode */
  1551.         taskHandle = paramPtr->params[0];
  1552.         ucase(*taskHandle);
  1553.         
  1554.         /* branch on the opcode */
  1555.         
  1556.         if (strcmp(*taskHandle,"ADD")==0) AddAMenu(paramPtr);                   
  1557.         else if (strcmp(*taskHandle,"DELETE")==0) DeleteAMenu(paramPtr);                        
  1558.         else if (strcmp(*taskHandle,"HIDE")==0) HideMenu(paramPtr);                     
  1559.         else if (strcmp(*taskHandle,"SHOW")==0) ShowMenu(paramPtr); 
  1560.         else if (strcmp(*taskHandle,"INSERT")==0) InsertMenuItem(paramPtr);                     
  1561.         else if (strcmp(*taskHandle,"REMOVE")==0) RemoveMenuItem(paramPtr);                     
  1562.         else if (strcmp(*taskHandle,"ENABLE")==0) EnableMenuItem(paramPtr); 
  1563.         else if (strcmp(*taskHandle,"DISABLE")==0) DisableMenuItem(paramPtr); 
  1564.         else if (strcmp(*taskHandle,"MARK")==0) MarkMenuItem(paramPtr); 
  1565.         else {
  1566.                 strcpy(temp,"MenuHandler Error: unknown message ");
  1567.                 strcat(temp,*taskHandle);
  1568.                 ResultIs(paramPtr,temp);
  1569.         }
  1570.         RestoreA4();    
  1571.  
  1572.         return;
  1573. }
  1574.  
  1575.